﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
//using LRSystem;

namespace LRSystem
{
    public class LoWOTRemoteTCP : ISender
    {
        private TcpClient client;
        private NetworkStream streamToClient;
        private const int BufferSize = 8192;
        private byte[] buffer;
        public delegate void ParsePacketDelegate(object sender, List<byte> rxPkt);
        public event ParsePacketDelegate EvParsePacket;
        public delegate void RemoteClientErrorDelegate(object sender, Exception ex);
        public static event RemoteClientErrorDelegate EvRemoteClientError;

        private List<byte> rxPacket = new List<byte>();

        public LoWOTRemoteTCP(TcpClient client)
        {
            this.client = client;
            this.EvParsePacket += LoWOTOriginalPacket.PacketParse;
            streamToClient = client.GetStream();                       // 获得流
            buffer = new byte[BufferSize];
            AsyncCallback callBack = new AsyncCallback(ReadComplete);  // 在构造函数中就开始准备读取
            streamToClient.BeginRead(buffer, 0, BufferSize, callBack, null);
        }

        private void ReadComplete(IAsyncResult ar) {
            int bytesRead = 0;
            try{
                lock(streamToClient) {
                    bytesRead = streamToClient.EndRead(ar);
                }
            if(bytesRead == 0) throw new Exception("Read 0 byte");
            
            //
            for (int i = 0; i < bytesRead; i++)
            {
                rxPacket.Add(buffer[i]);                                    // 将收到的所有数据存入list.
            }

            Array.Clear(buffer, 0, buffer.Length); // 清空缓存，避免脏读
            if (EvParsePacket != null)
                EvParsePacket(client, rxPacket);                             // 对收到的数据进行解析处理
                
            // 再次调用BeginRead()，完成时调用自身，形成无限循环
            lock(streamToClient) {
                AsyncCallback callBack = new AsyncCallback(ReadComplete);
                streamToClient.BeginRead(buffer, 0, BufferSize, callBack, null);
            }
           } catch(Exception ex) {

               if (EvRemoteClientError != null)
                  EvRemoteClientError(client, ex);
            
               if(streamToClient!=null)
                streamToClient.Dispose();

                client.Close();                
           }
        }

        //public void SendPacket(ISendPacket packet)
        //{
        //    byte[] Buf = packet.BuildCmd();
        //    if (Buf != null && streamToClient != null)
        //        this.streamToClient.Write(Buf, 0, Buf.Length);
        //}
    
    }
}
